//
//  ViewController.swift
//  MarkDownDemo
//
//  Created by nowcoder on 2024/12/18.
//

import UIKit
import MarkdownUIKit
import Down
import SnapKit

class ViewController: UIViewController {
    // MARK: - Properties
    private var markdownView: MarkdownContentView?
    private var editorView: UITextView = {
        let textView = UITextView()
        textView.font = .systemFont(ofSize: 16)
        textView.autocapitalizationType = .none
        textView.autocorrectionType = .no
        textView.isHidden = true
        return textView
    }()
    
    private lazy var themeButton: UIButton = {
        let button = UIButton(type: .system)
        if #available(iOS 13.0, *) {
            let image = UIImage(systemName: "moon.fill")
            button.setImage(image, for: .normal)
        } else {
            button.setTitle("主题", for: .normal)
        }
        button.addTarget(self, action: #selector(themeButtonTapped), for: .touchUpInside)
        return button
    }()
    
    private lazy var previewButton: UIButton = {
        let button = UIButton(type: .system)
        if #available(iOS 13.0, *) {
            let image = UIImage(systemName: "eye.fill")
            button.setImage(image, for: .normal)
        } else {
            button.setTitle("预览", for: .normal)
        }
        button.addTarget(self, action: #selector(previewButtonTapped), for: .touchUpInside)
        return button
    }()
    
    private var isDarkMode = false
    private var isPreviewMode = true
    private var keyboardHeight: CGFloat = 0
    private lazy var panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
    
    // MARK: - Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupNavigationBar()
        registerCustomViews()
        setupEditorView()
        loadMarkdown()
    }
    
    // MARK: - Setup
    private func setupUI() {
        view.backgroundColor = .systemBackground
        
        let markdownView = MarkdownContentView()
        markdownView.delegate = self
        view.addSubview(markdownView)
        view.addSubview(editorView)
        
        // 添加手势识别
        editorView.addGestureRecognizer(panGesture)
        panGesture.delegate = self
        
        // 更新约束，考虑键盘高度
        markdownView.snp.makeConstraints { make in
            make.top.left.right.equalTo(view.safeAreaLayoutGuide)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-keyboardHeight)
        }
        
        editorView.snp.makeConstraints { make in
            make.top.left.right.equalTo(view.safeAreaLayoutGuide)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-keyboardHeight)
        }
        
        self.markdownView = markdownView
        
        // 注册键盘通知
        registerKeyboardNotifications()
    }
    
    private func setupEditorView() {
        editorView.delegate = self
        editorView.text = TestResource.basicMarkdown
        
        // 添加工具栏
        let toolbar = UIToolbar()
        toolbar.sizeToFit()
        
        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissKeyboard))
        
        toolbar.items = [flexSpace, doneButton]
        editorView.inputAccessoryView = toolbar
    }
    
    private func setupNavigationBar() {
        title = "Markdown Editor"
        if #available(iOS 13.0, *) {
            navigationController?.navigationBar.prefersLargeTitles = true
            setupModernNavigationBar()
        } else {
            setupLegacyNavigationBar()
        }
    }
    
    @available(iOS 13.0, *)
    private func setupModernNavigationBar() {
        // 创建按钮容器视图
        let buttonStackView = UIStackView(arrangedSubviews: [themeButton, previewButton])
        buttonStackView.spacing = 16
        buttonStackView.distribution = .fillEqually
        
        // 设置导航栏右侧按钮
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: buttonStackView)
        
        // 添加代码样式按钮
        let codeStyleButton = UIButton(type: .system)
        codeStyleButton.setImage(UIImage(systemName: "chevron.left.forwardslash.chevron.right"), for: .normal)
        codeStyleButton.addTarget(self, action: #selector(showCodeStyleOptions), for: .touchUpInside)
        
        let leftStackView = UIStackView(arrangedSubviews: [codeStyleButton])
        leftStackView.spacing = 16
        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftStackView)
    }
    
    private func setupLegacyNavigationBar() {
        // iOS 13 以下的导航栏设置
        let themeItem = UIBarButtonItem(customView: themeButton)
        let previewItem = UIBarButtonItem(customView: previewButton)
        navigationItem.rightBarButtonItems = [previewItem, themeItem]
    }
    
    private func registerCustomViews() {
        // 注册引用标签视图
        markdownView?.registerCustomHTMLNodeView(forTag: "a", className: "ncTag") { [weak self] attributes, content in
            let label = PaddingLabel()
            label.numberOfLines = 0
            label.text = content
            
            // 设置样式
            let blueColor = self?.getSystemColor(
                light: UIColor(red: 0, green: 122/255, blue: 1, alpha: 1),
                dark: UIColor(red: 10/255, green: 132/255, blue: 1, alpha: 1)
            ) ?? .blue
            label.backgroundColor = blueColor.withAlphaComponent(0.1)
            label.textColor = blueColor
            label.font = .systemFont(ofSize: 16)
            label.layer.cornerRadius = 4
            label.layer.masksToBounds = true
            label.padding = UIEdgeInsets(top: 2, left: 4, bottom: 2, right: 4)
            
            // 启用用户交互
            label.isUserInteractionEnabled = true
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self?.handleReference(_:)))
            label.addGestureRecognizer(tapGesture)
            
            // 存储内容
            objc_setAssociatedObject(label, &AssociatedKeys.content, content, .OBJC_ASSOCIATION_RETAIN)
            
            return label
        }
        
        // 注册用户标签视图
        markdownView?.registerCustomHTMLNodeView(forTag: "a", className: "userTag") { [weak self] attributes, content in
            let label = PaddingLabel()
            label.numberOfLines = 0
            label.text = content
            
            // 设置样式
            let greenColor = self?.getSystemColor(
                light: UIColor(red: 52/255, green: 199/255, blue: 89/255, alpha: 1),
                dark: UIColor(red: 48/255, green: 209/255, blue: 88/255, alpha: 1)
            ) ?? .green
            label.backgroundColor = greenColor.withAlphaComponent(0.1)
            label.textColor = greenColor
            label.font = .systemFont(ofSize: 16)
            label.layer.cornerRadius = 4
            label.layer.masksToBounds = true
            label.padding = UIEdgeInsets(top: 2, left: 4, bottom: 2, right: 4)
            
            // 启用用户交互
            label.isUserInteractionEnabled = true
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self?.handleUserTag(_:)))
            label.addGestureRecognizer(tapGesture)
            
            // 存储内容
            objc_setAssociatedObject(label, &AssociatedKeys.content, content, .OBJC_ASSOCIATION_RETAIN)
            
            return label
        }
    }
    
    // MARK: - Code Style Menu
    @objc private func showCodeStyleOptions() {
        if #available(iOS 14.0, *) {
            // iOS 14+ 使用 UIMenu
            showModernCodeStyleMenu()
        } else {
            // iOS 13 使用 UIAlertController
            showLegacyCodeStyleMenu()
        }
    }
    
    @available(iOS 14.0, *)
    private func showModernCodeStyleMenu() {
        let codeStyleButton = navigationItem.leftBarButtonItem?.customView as? UIButton
        
        let menu = UIMenu(
            title: "Code Style",
            image: UIImage(systemName: "chevron.left.forwardslash.chevron.right"),
            children: [
                UIAction(
                    title: "Light",
                    image: UIImage(systemName: "sun.max")
                ) { [weak self] _ in
                    self?.updateCodeBlockStyle(.light)
                },
                UIAction(
                    title: "Dark",
                    image: UIImage(systemName: "moon")
                ) { [weak self] _ in
                    self?.updateCodeBlockStyle(.dark)
                },
//                UIAction(
//                    title: "Xcode",
//                    image: UIImage(systemName: "hammer")
//                ) { [weak self] _ in
//                    self?.updateCodeBlockStyle(.xcode)
//                },
                UIAction(
                    title: "GitHub",
                    image: UIImage(systemName: "terminal")
                ) { [weak self] _ in
                    self?.updateCodeBlockStyle(.github)
                }
            ]
        )
        
        codeStyleButton?.menu = menu
        codeStyleButton?.showsMenuAsPrimaryAction = true
    }
    
    private func showLegacyCodeStyleMenu() {
        let alert = UIAlertController(title: "Code Style", message: nil, preferredStyle: .actionSheet)
        
        let styles: [(title: String, style: CodeBlockStyle)] = [
            ("Light", .light),
            ("Dark", .dark),
//            ("Xcode", .xcode),
            ("GitHub", .github)
        ]
        
        for (title, style) in styles {
            alert.addAction(UIAlertAction(title: title, style: .default) { [weak self] _ in
                self?.updateCodeBlockStyle(style)
            })
        }
        
        alert.addAction(UIAlertAction(title: "取消", style: .cancel))
        
        // 对于 iPad，设置弹出位置
        if let popoverController = alert.popoverPresentationController,
           let buttonView = navigationItem.leftBarButtonItem?.customView {
            popoverController.sourceView = buttonView
            popoverController.sourceRect = buttonView.bounds
        }
        
        present(alert, animated: true)
    }
    
    // MARK: - Helper Methods
    private func updateCodeBlockStyle(_ style: CodeBlockStyle) {
        // 更新代码块样式
        markdownView?.updateCodeBlockStyle(style)
    }
    
    // MARK: - Associated Keys
    private struct AssociatedKeys {
        static var content = "content"
    }
    
    // MARK: - Actions
    @objc private func themeButtonTapped() {
        isDarkMode.toggle()
        
        // 更新按钮图标
        if #available(iOS 13.0, *) {
            let image = isDarkMode ? UIImage(systemName: "sun.max.fill") : UIImage(systemName: "moon.fill")
            themeButton.setImage(image, for: .normal)
            
            // 更新系统外观
            if let windowScene = view.window?.windowScene {
                windowScene.windows.forEach { window in
                    window.overrideUserInterfaceStyle = isDarkMode ? .dark : .light
                }
            }
        } else {
            // iOS 13 以下的主题切换
            view.backgroundColor = isDarkMode ? .black : .white
            editorView.backgroundColor = isDarkMode ? .black : .white
            editorView.textColor = isDarkMode ? .white : .black
        }
        
        // 更新 Markdown 内容的主题
        markdownView?.theme = isDarkMode ? .dark : .light
        markdownView?.reloadData()
    }
    
    @objc private func previewButtonTapped() {
        isPreviewMode.toggle()
        
        if #available(iOS 13.0, *) {
            let image = isPreviewMode ? UIImage(systemName: "eye.fill") : UIImage(systemName: "eye.slash.fill")
            previewButton.setImage(image, for: .normal)
        } else {
            previewButton.setTitle(isPreviewMode ? "预览" : "编辑", for: .normal)
        }
        
        // 更新视图显示状态
        UIView.animate(withDuration: 0.3) {
            self.markdownView?.isHidden = !self.isPreviewMode
            self.editorView.isHidden = self.isPreviewMode
        }
        
        // 如果切换到预览模式，更新预览内容
        if isPreviewMode {
            markdownView?.render(editorView.text)
        }
    }
    
    @objc private func dismissKeyboard() {
        editorView.resignFirstResponder()
    }
    
    @objc private func handleReference(_ sender: UITapGestureRecognizer) {
        guard let label = sender.view as? UILabel,
              let content = objc_getAssociatedObject(label, &AssociatedKeys.content) as? String else {
            return
        }
        print("Reference tapped: \(content)")
        // 处理引用点击...
    }
    
    @objc private func handleUserTag(_ sender: UITapGestureRecognizer) {
        guard let label = sender.view as? UILabel,
              let content = objc_getAssociatedObject(label, &AssociatedKeys.content) as? String else {
            return
        }
        print("User tag tapped: \(content)")
        // 处理用户标签点击...
    }
    
    // MARK: - Loading
    func loadMarkdown() {
        // 设置初始主题
        markdownView?.theme = isDarkMode ? .dark : .light
        
        // 设置初始代码块样式
        if #available(iOS 13.0, *) {
            markdownView?.updateCodeBlockStyle(.light)
        }
        
        // 设置图片基础 URL（如果需要）
        if let baseURL = Bundle.main.url(forResource: "Images", withExtension: nil) {
            markdownView?.imageBaseURL = baseURL
        }
        
        // 加载初始 Markdown 内容
        if let markdownContent = editorView.text {
            markdownView?.render(markdownContent)
        }
    }
    
    // MARK: - Custom Link Handling
    private func handleCustomLink(_ url: URL) {
        guard let host = url.host else { return }
        
        switch host {
        case "reference":
            if let reference = url.pathComponents.last {
                handleReferenceLink(reference)
            }
        case "user":
            if let username = url.pathComponents.last {
                handleUserLink(username)
            }
        case "image":
            if let imageName = url.pathComponents.last {
                handleImageLink(imageName)
            }
        default:
            break
        }
    }
    
    private func handleReferenceLink(_ reference: String) {
        // 处理引用链接
        print("Handling reference: \(reference)")
        // 可以在这里添加跳转到引用页面的逻辑
    }
    
    private func handleUserLink(_ username: String) {
        // 处理用户链接
        print("Handling user: \(username)")
        // 可以在这里添加跳转到用户页面的逻辑
    }
    
    private func handleImageLink(_ imageName: String) {
        // 处理图片链接
        print("Handling image: \(imageName)")
        // 可以在这里添加图片预览逻辑
    }
    
    // MARK: - Image Preview
    private func showImagePreview(_ url: URL) {
        let imagePreviewVC = ImagePreviewViewController(imageURL: url)
        present(imagePreviewVC, animated: true)
    }
    
    // MARK: - Helper Methods
    private func getSystemColor(light: UIColor, dark: UIColor) -> UIColor {
        if #available(iOS 13.0, *) {
            return UIColor { traitCollection in
                return traitCollection.userInterfaceStyle == .dark ? dark : light
            }
        } else {
            return light
        }
    }
    
    // MARK: - Keyboard Notifications
    private func registerKeyboardNotifications() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillShow),
            name: UIResponder.keyboardWillShowNotification,
            object: nil
        )
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillHide),
            name: UIResponder.keyboardWillHideNotification,
            object: nil
        )
    }
    
    @objc private func keyboardWillShow(_ notification: Notification) {
        guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else {
            return
        }
        
        keyboardHeight = keyboardFrame.height
        updateViewsForKeyboard()
    }
    
    @objc private func keyboardWillHide(_ notification: Notification) {
        keyboardHeight = 0
        updateViewsForKeyboard()
    }
    
    private func updateViewsForKeyboard() {
        UIView.animate(withDuration: 0.3) {
            self.markdownView?.snp.updateConstraints { make in
                make.bottom.equalTo(self.view.safeAreaLayoutGuide).offset(-self.keyboardHeight)
            }
            
            self.editorView.snp.updateConstraints { make in
                make.bottom.equalTo(self.view.safeAreaLayoutGuide).offset(-self.keyboardHeight)
            }
            
            self.view.layoutIfNeeded()
        }
    }
    
    // MARK: - Pan Gesture Handling
    @objc private func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
        let translation = gesture.translation(in: view)
        let velocity = gesture.velocity(in: view)
        
        switch gesture.state {
        case .changed:
            if !isPreviewMode && translation.y > 0 {
                dismissKeyboard()
            }
        case .ended:
            if velocity.y > 1000 {
                dismissKeyboard()
            }
        default:
            break
        }
    }
}

// MARK: - UITextViewDelegate
extension ViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        // 实时预览更新
        if isPreviewMode {
            markdownView?.render(textView.text)
        }
    }
}

// MARK: - MarkdownContentViewDelegate
extension ViewController: MarkdownContentViewDelegate {
    func markdownContentView(_ view: MarkdownContentView, didTapImage url: URL) {
        print("Tapped image: \(url)")
    }
    
    func markdownContentView(_ view: MarkdownContentView, shouldHandleLink url: URL) -> Bool {
        // 处理特殊链接
        if url.scheme == "custom" {
            handleCustomLink(url)
            return false
        }
        return true
    }
    
    func markdownContentView(_ view: MarkdownContentView, didHandleLink url: URL) {
        print("Successfully handled link: \(url)")
    }
    
    func markdownContentView(_ view: MarkdownContentView, failedToHandleLink url: URL, error: Error) {
        print("Failed to handle link: \(url), error: \(error)")
    }
    
    func markdownContentView(_ view: MarkdownContentView, didTapCustomTag tag: String, attributes: [String: String], content: String) {
        // 处理标签点击事件
        if tag.lowercased() == "a" && attributes["class"] == ".ncTag" {
            print("Reference tapped: \(content)")
            // 处理引用点击...
        }
    }
    
    func markdownContentView(_ view: MarkdownContentView, didLoadImage image: UIImage, from url: URL) {
        print("Image loaded successfully: \(url)")
        print("Image size: \(image.size)")
    }
}

// MARK: - UIGestureRecognizerDelegate
extension ViewController: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

